package gameLogic

import (
	"math/rand"
	"sync"
	"time"

	"github.com/sirupsen/logrus"
)

//保存战斗场景
type BattleScene struct {
	epoch             uint64
	enemy             *Enemy
	extra             map[string]string
	IsDead            bool  //死亡时设置true
	playerReliveEpoch int64 //玩家死亡后复活需要的Epoch，死亡时会设置，然后每一次循环都会自减
}

func (s *BattleScene) isAlive() bool {
	s.playerReliveEpoch--
	return s.playerReliveEpoch >= 0
}

func (s *BattleScene) init() {
	s.extra = make(map[string]string)
	s.epoch = 0
	s.playerReliveEpoch = 0
	s.IsDead = false
}

type SceneFirst struct {
	rwLock       sync.RWMutex
	enemyProb    float64                   //遇敌概率
	uidEnemyList map[string](*BattleScene) //uid的战斗信息
	sceneName    string                    //场景名
}

func (s *SceneFirst) Init() {
	rand.Seed(time.Now().Unix())
	s.uidEnemyList = make(map[string]*BattleScene)
	s.enemyProb = 0.5
	s.sceneName = kDefaultScene

	//添加怪物
	var EnemySlime Enemy
	EnemySlime.Props.Attack = 10
	EnemySlime.Props.Exp = 10
	EnemySlime.Props.Hp = 100
	EnemySlime.Props.Speed = 20
	EnemySlime.Props.PhyDefence = 30
	AddEnemy(kDefaultScene, EnemySlime)
}
func (s *SceneFirst) Timer() {

}

func (s *SceneFirst) UpdateEnemy(uid string, enemy *Enemy) {
	(s.uidEnemyList[uid]).enemy = enemy
}

func (s *SceneFirst) Logic(uid string, info UserInfo) {
	//新手村的场景逻辑，有可能多个协程都会访问，需要加锁
	/*
		1. 判断内存的uidEnemyList是否有玩家
		2. 没有则生成怪物（有概率）
		3. 有则按照epoch去处理伤害，血量的战斗逻辑
		4. 等到某一方死亡后，结算数据时，更新回redis
		5. 继续逻辑

		这里暂时不推送战斗信息给到客户端，因为只有一个客户端不方便
		后面需要再开一个端口来进行数据下发
	*/
	s.rwLock.Lock()
	defer s.rwLock.Unlock()
	if battleScene, ok := s.uidEnemyList[uid]; ok {
		battleScene.epoch += 1
		//判断是否处于复活期间
		if (battleScene).isAlive() {
			logrus.Infof("uid:%s is during alive, %d epoch left.", uid, battleScene.playerReliveEpoch)
			return
		}

		// 刚复活，则返回，并且清除对象，等下一个epoch再生成怪物
		if battleScene.IsDead {
			logrus.Infof("uid:%s is live again!", uid)
			delete(s.uidEnemyList, uid)
			return
		}

		//战斗逻辑
		enemy := battleScene.enemy //拿到怪物实例
		isAttack := false
		//stage1. 玩家攻击怪物
		if IsCanAttack(&info.Props, battleScene.epoch) { //攻击速度判定
			isAttack = true
			AttackLogic(&info.Props, &enemy.Props)
		}

		//stage2. 怪物攻击玩家
		if IsCanAttack(&enemy.Props, battleScene.epoch) { //攻击速度判定
			isAttack = true
			AttackLogic(&enemy.Props, &info.Props)

		}
		if isAttack {
			logrus.Infof("uid hp:%d, enemy hp:%d", info.Props.Hp, enemy.Props.Hp)
			UpdateUserInfo(uid, info) //更新战斗后玩家的属性
		}

		//stage3. 判断战斗结果
		if info.Props.IsDead() { //如果玩家死亡
			logrus.Infof("uid:%s is dead! waiting for 5 second to relive.", uid)
			battleScene.playerReliveEpoch = 50 //死亡后5秒复活
			battleScene.IsDead = true
			return
		}

		if enemy.Props.IsDead() { //怪物死亡，则清除战斗，继续找怪，结算等逻辑
			logrus.Infof("enemy %s is killed by %s, uid hp: %d", enemy.Props.ObjName, uid, info.Props.Hp)
			delete(s.uidEnemyList, uid)
			return
		}
	} else {
		//没有怪物

		//stage1. 判断概率，是否生成怪物
		if !IsInProb(s.enemyProb) {
			logrus.Infof("user %s is looking for enemy...", uid)
			return
		}
		//stage2. 生成怪物
		enemyIns := GetRandomEnemy(s.sceneName)
		battleScene := BattleScene{}
		battleScene.enemy = enemyIns
		battleScene.init()
		//stage3. 填充到map，等下一个epoch去打怪
		s.uidEnemyList[uid] = &battleScene
		logrus.Infof("user %s has meet enemy!", uid)
	}
}
